﻿<html>
	
<head>
	<title>6. Продвинутые возможности</title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="generator" content="HelpNDoc Personal Edition 3.9.1.648">
	<link type="text/css" rel="stylesheet" media="all" href="css/reset.css" />
	<link type="text/css" rel="stylesheet" media="all" href="css/base.css" />
	<link type="text/css" rel="stylesheet" media="all" href="css/hnd.css" />
	<!--[if lte IE 8]>
		<link type="text/css" rel="stylesheet" media="all" href="css/ielte8.css" />
	<![endif]-->
	<style type="text/css">
		#topic_header
		{
			background-color: #EFEFEF;
		}
	</style>
	<script type="text/javascript" src="js/jquery.min.js"></script>
	<script type="text/javascript" src="js/hnd.js"></script>
	<script type="text/javascript">
		$(document).ready(function()
		{
			if (top.frames.length == 0)
			{
				var sTopicUrl = top.location.href.substring(top.location.href.lastIndexOf("/") + 1, top.location.href.length);
				top.location.href = "index.html?" + sTopicUrl;
			}
			else if (top && top.FrameTOC && top.FrameTOC.SelectTocItem)
			{
				top.FrameTOC.SelectTocItem("AdvancedFeatures");
			}
		});
	</script>
</head>

<body>

	<div id="topic_header">
			<div id="topic_header_content">
				<h1>6. Продвинутые возможности</h1>
				
				<div id="topic_breadcrumb">
					<a href="BeginnersGuide.html">Курс для новичка</a> &rsaquo;&rsaquo; </div>
				</div>
			<div id="topic_header_nav">
				<a href="BeginnersGuide.html"><img src="img/arrow_up.png" alt="Parent"/></a>
				
				<a href="ProgramCustomization.html"><img src="img/arrow_left.png" alt="Previous"/></a>
				
				<a href="Reference.html"><img src="img/arrow_right.png" alt="Next"/></a>
				
				</div>
			<div class="clear"></div>
		</div>
	<div id="topic_content">
		
<p></p>
<p><span class="rvts20">Продвинутые возможности</span></p>
<p class="rvps2"><span class="rvts39"><br/></span></p>
<p class="rvps2"><span class="rvts39"><br/></span></p>
<p class="rvps14"><a class="rvts28" href="AdvancedFeatures.html#ProjectsSharing">1. Как делиться проектами.</a></p>
<p class="rvps14"><a class="rvts28" href="AdvancedFeatures.html#UsingPatterns">2. Использование шаблонов.</a></p>
<p class="rvps14"><a class="rvts28" href="AdvancedFeatures.html#UsingMarkers">3. Эффективное использование Маркеров.</a></p>
<p class="rvps14"><a class="rvts28" href="AdvancedFeatures.html#UsingLua">4. Использование Lua.</a></p>
<p class="rvps10"><span class="rvts23"><br/></span></p>
<hr style="height: 1px; color : #000000;  background-color : #000000; border-width : 0px;"/>
<p class="rvps2"><a name="ProjectsSharing"></a>
<span class="rvts54"><br/></span></p>
<p class="rvps10"><span class="rvts23">1. Как делиться проектами.</span></p>
<p class="rvps10"><span class="rvts22"><br/></span></p>
<p class="rvps10"><span class="rvts22">Проект Тасэдитора сохраняется на диске в виде fm3-файла. В этом файле сохраняются все существенные аспекты работы, чтобы можно было в точности восстановить отложенное состояние рабочего процесса. Размер этого "мгновенного снимка" может занимать немало места (в зависимости от объёма Гринзоны он может составлять сотни мегабайт).</span></p>
<p class="rvps10"><span class="rvts22">Поэтому в случаях, когда вам нужно выложить проект в Интернете (например, для опубликования), имеет смысл сохранять в проекте не полный снимок рабочего процесса, а только необходимую информацию. Для этого нужно выбрать в меню Тасэдитора пункт </span><span class="rvts26">File -&gt; Save Compact</span><span class="rvts22">. Появится окно, где можно выбрать, какие аспекты рабочего процесса следует сохранить в файл.</span></p>
<p class="rvps10"><img align="left" alt="" style="padding : 6px;" src="lib/save-compact.png"/></p>
<p class="rvps10"><span class="rvts26">Binary format of Input</span><span class="rvts22"> – сохранять Ввод мувика в двоичном формате. Эта настройка относится к особенностям формата fm2, расширением которого является fm3-формат. По умолчанию галочка установлена. Если снять её, Ввод будет записан в fm3-файл в текстовом формате, что увеличит размер &nbsp;файла, но позволит редактировать его в любом текстовом редакторе. Однако Тасэдитор гораздо лучше приспособлен к редактированию мувиков, поэтому рекомендуется оставить эту галочку установленной и воздержаться от изменений содержимого fm3-файлов вне Тасэдитора. В некомпактных fm3-проектах (сохраняемых обычным способом) Ввод сохраняется в двоичном формате.</span></p>
<p class="rvps10"><span class="rvts26">Markers</span><span class="rvts22"> – сохранять Маркеры в файл. Ввод будет сохраняться в любом случае, так как без Ввода невозможно будет открыть fm3-файлы в эмуляторе. Без Маркеров проигрывание fm3-мувиков возможно, поэтому вы можете снять эту галочку, если не хотите выкладывать Маркеры. Но такие проекты не многим будут отличаться от fm2-мувиков, поэтому рекомендуется оставить эту галочку установленной, чтобы передать в компактном проекте все текущие Маркеры и их Заметки. Размер файла при этом увеличится незначительно.</span></p>
<p class="rvps10"><span class="rvts26">Bookmarks</span><span class="rvts22"> – сохранять Закладки в файл. Сохраняются данные всех имеющихся в проекте Закладок и их ответвлений. Рекомендуется оставить эту галочку установленной. Размер файла увеличится незначительно.</span></p>
<p class="rvps10"><span class="rvts26">History</span><span class="rvts22"> – сохранять Журнал Истории в файл. Размер файла увеличится на несколько мегабайт. Обычно нет смысла публиковать данные для отката изменений. Поэтому рекомендуется оставить эту галочку снятой. Когда вы открываете fm3-проект без журнала Истории, Тасэдитор создаёт его автоматически.</span></p>
<p class="rvps10"><span class="rvts26">Piano Roll</span><span class="rvts22"> – сохранять текущую позицию вертикального скроллинга Piano Roll, чтобы при открытии проекта сразу увидеть тот же самый участок. Размер файла увеличится незначительно, поэтому можно оставить галочку установленной.</span></p>
<p class="rvps10"><span class="rvts26">Selection</span><span class="rvts22"> – сохранять все данные Выделения в файл. Сохраняется как текущее Выделение (если есть), так и История Выделений. Размер файла увеличится незначительно, однако обычно нет смысла оставлять эти данные в публикуемом проекте. Поэтому рекомендуется оставить эту галочку снятой.</span></p>
<p class="rvps10"><span class="rvts26">Greenzone saving options</span><span class="rvts22"> – здесь можно выбрать способ сохранения Гринзоны: Именно из-за Гринзоны проекты занимают так много места на диске. Поэтому рекомендуется выбрать частичное сохранение или вовсе не сохранять Гринзону.</span></p>
<ul style="text-indent: 30px; margin-left: 0px; list-style-position: inside;">
<li class="rvps10"><span class="rvts26">all frames</span><span class="rvts22"> – сохранить всю Гринзону. Размер файла значительно увеличится!</span></li>
<li class="rvps10"><span class="rvts26">every 16th frame</span><span class="rvts22"> – сохранить только каждый 16-й кадр. Размер файла значительно увеличится.</span></li>
<li class="rvps10"><span class="rvts26">marked frames</span><span class="rvts22"> – сохранить только кадры, на которых стоят Маркеры. Размер файла увеличится в зависимости от количества Маркеров в проекте.</span></li>
<li class="rvps10"><span class="rvts26">don't save</span><span class="rvts22"> – не сохранять Гринзону. Если Курсор Проигрывателя в момент компактного сохранения проекта находится на начальном кадре мувика, в компактном fm3 вообще не будет ни одного сэйва Гринзоны. Но если Курсор Проигрывателя остался внутри мувика, в fm3 попадает один сэйв Гринзоны, позволяющий при открытии проекта восстановить состояние эмулятора на кадр Курсора Проигрывателя. Один сэйв занимает очень мало места, поэтому файл остаётся компактным.</span></li>
</ul>
<p class="rvps10"><span class="rvts22"><br/></span></p>
<p class="rvps10"><span class="rvts22">В результате компактного сохранения вы можете получить fm3-проект размером менее полумегабайта, при этом передавая в файле не только текущий мувик, но и все существенные данные, которые могут понадобиться получателю. Например, если вы работаете в соавторстве с другим ТАСером, нужно обмениваться не только Вводом, но и Маркерами, и Закладками. А Гринзону получатель файла сможет воссоздать самостоятельно, просто запустив просмотр в Тасэдиторе.</span></p>
<p class="rvps10"><span class="rvts22">При сохранении компактного проекта к имени файла добавляется суффикс "-compact". Компактное сохранение проекта не заменяет обычное сохранение, поэтому, если в проекте имеются несохранённые изменения, звёздочка из заголовка окна не исчезнет после Save Compact.</span></p>
<p class="rvps10"><img align="left" alt="" style="padding : 6px;" src="lib/export-to-fm2.png"/></p>
<p class="rvps10"><span class="rvts22">Помимо сохранения компактного fm3 вы ещё можете экспортировать данные мувика в формат fm2, принятый на сайте TASVideos задолго до возникновения Тасэдитора. В этом формате вы передаёте только Ввод. Для этого нужно выбрать в меню Тасэдитора пункт </span><span class="rvts26">File -&gt; Export to FM2</span><span class="rvts22">. Появится окно, где можно выбрать формат &nbsp;целевого мувика (1P, 2P или Fourscore).</span></p>
<p class="rvps10"><span class="rvts22">Так как формат FM2 поддерживает хранение текстовых субтитров, можно использовать Заметки Маркеров в качестве материала для субтитров. Для этого нужно установить галочку "Convert Marker Notes to Movie Subtitles". Тогда при просмотре полученного fm2-мувика зрители будут видеть текстовые сообщения, появляющиеся во время проигрывания тех кадров, где стояли соответствующие Маркеры в вашем проекте. А при необходимости можно далее конвертировать fm2-субтитры в общепринятый формат ".srt" для выкладывания ТАСа на Youtube. Для этого надо при проигрывании fm2 в FCEUX щёлкнуть правой кнопкой по игровому окну и в появившемся контекстном меню выбрать пункт "Dump Subtitles to SRT file".</span></p>
<p class="rvps10"><span class="rvts22">FM2-файлы можно открывать в Тасэдиторе точно так же, как FM3-проекты. Для этого в окне выбора файла (</span><span class="rvts26">File -&gt; Open</span><span class="rvts22">) нужно переключиться на фильтр "All Files (*.*)" и выбрать требуемый fm2-мувик. Тасэдитор выдаст сообщение о том, что данный файл не является проектом и потребует подтверждения загрузки. При положительном ответе Тасэдитор создаст новый проект, используя Ввод и настройки из данного fm2-файла.</span></p>
<p class="rvps10"><span class="rvts22">Кроме того, вы можете импортировать Ввод из любого fm2 или fm3-файла с помощью </span><span class="rvts26">File -&gt; Import Input</span><span class="rvts22">. При этом не создаётся новый проект, просто текущий Ввод вашего проекта массово заменяется на Ввод из файла. Эта операция похожа на операцию "Вставка из Буфера Обмена", она заносится в Журнал Истории вашего проекта, и её можно откатить с помощью </span><span class="rvts34">Ctrl + Z</span><span class="rvts22">.</span></p>
<p class="rvps10"><span class="rvts22"><br/></span></p>
<hr style="height: 1px; color : #000000;  background-color : #000000; border-width : 0px;"/>
<p class="rvps10"><a name="UsingPatterns"></a>
<span class="rvts22"><br/></span></p>
<p class="rvps10"><span class="rvts23">2. Использование шаблонов.</span></p>
<p class="rvps10"><span class="rvts22"><br/></span></p>
<p class="rvps10"><span class="rvts22">При редактировании Ввода ТАСер фактически составляет уникальную последовательность нажатий и отпусканий для каждой кнопки джойстика. Но, несмотря на уникальность, в составе этой большой последовательности зачастую можно выявить однотипные участки, представляющие собой короткую последовательность нажатий и отпусканий, &nbsp;которая повторяется несколько раз подряд, либо встречается многократно в разных местах мувика.</span></p>
<p class="rvps10"><span class="rvts22">Для ускорения работы можно запомнить такие типичные или часто используемые последовательности &nbsp;в виде </span><span class="rvts31">шаблонов</span><span class="rvts22">, чтобы устанавливать их парой щелчков, не рисуя каждое нажатие по отдельности.</span></p>
<p class="rvps10"><span class="rvts22">Шаблоны полезны в нескольких случаях:</span></p>
<ul style="text-indent: 30px; margin-left: 0px; list-style-position: inside;">
<li class="rvps10"><span class="rvts22">когда одинаковая последовательность часто используется в мувике (например, размеренное чередование нажатий и отпускания кнопки </span><span class="rvts32">B</span><span class="rvts22">)</span></li>
<li class="rvps10"><span class="rvts22">когда одну и ту же последовательность требуется рисовать для нескольких кнопок (например, чередовать </span><span class="rvts32">L</span><span class="rvts22"> и </span><span class="rvts32">R</span><span class="rvts22">)</span></li>
<li class="rvps10"><span class="rvts22">когда одну и ту же последовательность требуется рисовать (или перерисовывать) много раз (например, разбег двойным нажатием </span><span class="rvts32">R</span><span class="rvts22">)</span></li>
</ul>
<p class="rvps10"><span class="rvts22">Несколько наиболее очевидных шаблонов уже добавлено в файл автором. Чтобы добавить свой шаблон, нужно отредактировать в любом текстовом редакторе (например, в Блокноте) файл </span><span class="rvts21">taseditor_patterns.txt</span><span class="rvts22">, находящийся в подпапке </span><span class="rvts21">/tools</span><span class="rvts22"> папки FCEUX. Каждая нечётная строчка этого файла обозначает название шаблона, каждая чётная строчка содержит закодированную последовательность состояний кнопки. Кодировка очень простая – единицей обозначается состояние "кнопка нажата", нулём обозначается состояние "кнопка отпущена".</span></p>
<p class="rvps10"><span class="rvts22">Каждый шаблон является зацикленным, то есть, когда Ввод по короткому шаблону устанавливается в длинный промежуток кадров, шаблон повторяется нужное количество раз, чтобы заполнить требуемый промежуток.</span></p>
<p class="rvps10"><img align="right" alt="" style="padding : 6px;" src="lib/patterns-menu.png"/></p>
<p class="rvps10"><span class="rvts22">При добавлении или изменении шаблона необходимо перезапустить Тасэдитор, чтобы новые данные были прочитаны из файла. Список доступных шаблонов находится в верхнем правом углу окна TAS Editor. Для смены текущего шаблона нужно зайти в это меню и щёлкнуть по названию желаемого шаблона. Для облегчения ориентирования в шаблонах рекомендуется отражать в названии каждого шаблона его игровое значение.</span></p>
<p class="rvps10"><span class="rvts22">Для применения текущего шаблона Тасэдитору нужно знать начало и конец промежутка, в котором указанная кнопка будет нажиматься и отпускаться по заданному правилу. Существует 3 разных способа применить шаблон:</span></p>
<p class="rvps10"><span class="rvts26">1 способ. </span><span class="rvts22">Указать и щёлкнуть по начальному кадру (в любой колонке Piano Roll, кроме колонки иконок), чтобы этот кадр стал выделенным. Затем зажать клавишу </span><span class="rvts34">Alt</span><span class="rvts22"> и щёлкнуть по конечному кадру в колонке редактируемой кнопки. В промежутке между двумя этими кадрами появится требуемая последовательность нажатий и отпусканий указанной кнопки. Этот способ удобно использовать, когда начальный кадр уже и так выделен из-за предыдущих щелчков по Piano Roll, и остаётся только зажать </span><span class="rvts34">Alt</span><span class="rvts22"> и сделать один щелчок по конечному кадру.</span></p>
<p class="rvps10"><span class="rvts26">2 способ.</span><span class="rvts22"> Щёлкнуть левой кнопкой мыши по начальному кадру в колонке редактируемой кнопки и зажать левую кнопку мыши, начав рисование. Зажать клавишу </span><span class="rvts34">Alt</span><span class="rvts22"> и переместить курсор мыши вверх или вниз. Таким образом вы будете </span><span class="rvts31">рисовать</span><span class="rvts22"> шаблонную последовательность нажатий и отпусканий указанной кнопки.</span></p>
<p class="rvps10"><span class="rvts26">3 способ.</span><span class="rvts22"> Выделить регион кадров, а затем зажать клавишу </span><span class="rvts34">Alt</span><span class="rvts22"> и щёлкнуть левой кнопкой мыши по символу редактируемой кнопки в Заголовке Piano Roll. В выделенной области появится требуемая последовательность нажатий и отпусканий указанной кнопки.</span></p>
<p class="rvps10"><span class="rvts22"><br/></span></p>
<p class="rvps10"><span class="rvts22">При использовании традиционного метода ТАСинга вы также можете применять шаблоны к записываемым последовательностям, но с гораздо меньшим удобством. Для этого нужно установить галочку </span><a class="rvts28" href="Toolbox.html#UsePattern">Use pattern</a><span class="rvts22"> в панели Рекордера. При этом вам может сначала потребоваться запись кнопок, которые не нужно чередовать (их следует записать без галочки Use pattern), а затем на том же участке с помощью Superimpose можно записать остальные кнопки по шаблону.</span></p>
<p class="rvps10"><span class="rvts22">Например, вам нужно записать стрельбу очередью во время перепрыгивания ямы. Сначала запишите процесс перепрыгивания без стрельбы, затем вернитесь Курсором Проигрывателя в начало участка (прыжком на оставленную здесь Закладку), включите галочки Superimpose и Use pattern, зажмите кнопку </span><span class="rvts32">B</span><span class="rvts22"> и отпустите паузу эмуляции. На текущем участке произойдёт объединение Ввода прыжка с шаблонным Вводом стрельбы.</span></p>
<p class="rvps10"><span class="rvts22">До Тасэдитора вместо шаблонов существовала похожая концепция "Autofire". Однако из-за неудобств метода Записи она почти не использовалась, потому что во время впечатывания Ввода обычно проще нажимать и отпускать нужные кнопки вручную. Поэтому, если вы ограничиваетесь традиционным методом, вы, скорее всего, не будете пользоваться шаблонами. Однако в нелинейном и полуавтоматическом методе шаблоны рисуются так же быстро, как простые зажатия кнопок, и здесь они действительно могут повысить скорость работы.</span></p>
<p class="rvps10"><span class="rvts22"><br/></span></p>
<p class="rvps10"><span class="rvts22">Шаблоны используются при создании последовательностей для любой отдельно взятой кнопки. А когда нужно вставить типовую комбинацию сразу нескольких кнопок, следует воспользоваться функциями Copy/Paste.</span></p>
<p class="rvps10"><span class="rvts22"><br/></span></p>
<hr style="height: 1px; color : #000000;  background-color : #000000; border-width : 0px;"/>
<p class="rvps10"><a name="UsingMarkers"></a>
<span class="rvts22"><br/></span></p>
<p class="rvps10"><span class="rvts23">3. Эффективное использование Маркеров.</span></p>
<p class="rvps10"><span class="rvts22"><br/></span></p>
<p class="rvps10"><span class="rvts22">Маркеры предназначены для упрощения сложных ситуаций за счёт структуризации проблемы. Когда в игре требуется проделать (или обмозговать) несколько комплексных действий, следует разбить большой участок на отдельные интервалы, чтобы чётко понимать, когда заканчивается одно действие и начинается другое. Даже если первоначальное разбиение окажется ошибочным, оно поможет привести ваши мысли в порядок.</span></p>
<p class="rvps10"><span class="rvts22">Естественно, не имеет смысла ставить Маркеры на ничем не примечательных участках, многие из которых даже не требуется шлифовать (достаточно, например, просто зажать </span><span class="rvts32">R</span><span class="rvts22">). А вот ключевые моменты и памятные ситуации мувика следует не только отмечать Маркерами, но и комментировать Заметками. Это позволит вам держать в голове мысленный образ всего проекта, а также осуществлять навигацию по тексту.</span></p>
<p class="rvps10"><span class="rvts22">Не требуется писать в Заметках литературные произведения. Можно ограничиться простыми словами-метками, числами, тегами. Слова придумаете на ходу, тут главное – соблюдать системный подход. То есть, если в начале первого уровня (на экране перехода) вы поставили Маркер с Заметкой "level 1 start", то и в начале второго уровня следует написать "level 2 start", а не что-нибудь вроде "act II begin". Во время создания ТАСа у вас в голове непринуждённо формируется уникальный глоссарий, состоящий из понятий, актуальных для данной игры. &nbsp;И чем более системный подход вы применяете к написанию Заметок, тем проще будет охарактеризовать очередной (похожий) участок, а значит, понять очередную задачу. И тем проще будет перемещаться между однотипными событиями мувика, а также находить старые участки Ввода, помня только их смутный образ в игре.</span></p>
<p class="rvps10"><span class="rvts22">Задачи, предлагаемые игроку в видеоиграх, очень часто повторяются. Детали и антураж могут меняться, но действия игрока остаются примерно теми же. В ряде случаев можно просто скопировать Ввод (решение подобной задачи из предыдущего уровня), и он успешно синхронизируется с новой игровой ситуацией (вероятно, понадобится небольшая подгонка). Только после копипаста рекомендуется всё же разнообразить Ввод, чтобы зрители ТАСа не заметили повторения и не заскучали.</span></p>
<p class="rvps10"><span class="rvts22">Например, в начале многих уровней Super Mario Bros ТАСеру необходимо использовать одинаковую последовательность нажатий кнопок, чтобы оптимально разогнаться до максимальной скорости. Предположим, что вы добросовестно комментируете Ввод по ходу ТАСинга. Значит, в первом уровне на месте разгона вы, вероятно, оставили Заметку со словами вроде "acceleration" или тому подобными фразами по своему усмотрению. Теперь, когда в новом уровне вы начинаете создавать Ввод для участка с той же самой задачей, вы ставите в начало участка Маркер и пишете к нему Заметку, характеризующую текущую задачу. Очевидно, что в тексте Заметки тоже окажется слово "acceleration", потому что требуется разгон.</span></p>
<p class="rvps10"><img align="right" alt="" style="padding : 6px;" src="lib/toolbox-selection.png"/></p>
<p class="rvps10"><span class="rvts22">И вот здесь уже можно воспользоваться функцией автоматического поиска похожих Заметок. Оставьте Курсор Проигрывателя на текущем участке и нажмите кнопку "</span><span class="rvts32">Similar</span><span class="rvts22">" в самом низу панели инструментов. Курсор Выделения сразу же прыгнет к Маркеру, который содержит наиболее похожую Заметку по мнению Тасэдитора. Скорее всего, это будет Маркер в начале участка, отвечающего за разгон в первом уровне. Поэтому вы можете сразу выделить весь Ввод на этом участке, нажав </span><span class="rvts34">Ctrl + A</span><span class="rvts22">, скопировать его в Буфер Обмена (</span><span class="rvts34">Ctrl + C</span><span class="rvts22">), а затем вернуться к текущему участку (дважды нажать </span><span class="rvts34">Shift</span><span class="rvts22">) и вставить из Буфера Обмена (</span><span class="rvts34">Ctrl + V</span><span class="rvts22">).</span></p>
<p class="rvps10"><span class="rvts22">Если первый результат поиска не подходит, можно нажимать кнопку </span><span class="rvts32">More</span><span class="rvts22">, чтобы переходить к следующим вариантам похожих Заметок. Обычно нужный участок обнаруживается в числе первых предложенных вариантов, конечно, при условии, что этот участок был отмечен Маркером с разумной Заметкой.</span></p>
<p class="rvps10"><span class="rvts22">Интересный факт: при написании Заметки к второму разгону слово "acceleration" появляется в тексте не нарочно, а потому что одинаковые игровые ситуации в целом описываются одинаковыми словами. Поэтому запоминать текст старых Заметок совершенно не требуется. В нужное время адекватные слова придут в голову сами.</span></p>
<p class="rvps10"><span class="rvts22">Таким образом вы прямо в процессе ТАСинга формируете </span><span class="rvts26">библиотеку полезных комбинаций Ввода</span><span class="rvts22">, наподобие вышеописанного списка шаблонов, только без необходимости явно заготавливать последовательности кнопок – они появляются естественным путём во время оформления и оптимизации участков, и хранятся они прямо в мувике, а не во внешнем файле. А при улучшении какой-либо комбинации (например, если вы найдёте более быстрый способ осуществлять разгон) можно будет быстро найти и исправить все участки, где используется эта комбинация. Также здесь вам не требуется помнить точное описание или имя нужной последовательности, ведь если вы соблюдаете системный подход к формулировке задач, используемые слова будут частично совпадать (а полное совпадение не требуется, алгоритм автопоиска достаточно умный).</span></p>
<p class="rvps10"><span class="rvts22">Автопоиск также удобно использовать для прыжков между двумя (и более) взаимосвязанными участками, разнесёнными в мувике достаточно далеко. Скроллировать Piano Roll колесом мыши или прыгать через десятки Маркеров от одного участка к другому будет не столь оперативно, как сделать щелчок по кнопке "</span><span class="rvts32">Similar</span><span class="rvts22">" или "</span><span class="rvts32">More</span><span class="rvts22">". Чтобы алгоритм мог мгновенно найти участки-близнецы (или участок-источник и участок-приёмник), имеет смысл написать в их Заметках уникальное слово, которое не используется в других местах.</span></p>
<p class="rvps10"><span class="rvts22">Например, в игре Megaman с каждым робот-мастером необходимо драться дважды (во второй раз в конце игры). Логично предположить, что обе битвы будут озаглавлены Маркерами с Заметками, содержащими имя робота и слова "boss" или "fight", или что-то в этом духе. В результате, когда Курсор Проигрывателя находится на одном из этих двух мест, нажатие кнопки </span><span class="rvts32">Similar</span><span class="rvts22"> перебросит вас к другому.</span></p>
<p class="rvps10"><span class="rvts22">В этом примере подходящие слова при написании Заметки нашлись без раздумий, при этом они достаточно уникальны, чтобы не повторяться в других местах мувика (по крайней мере не в том же наборе слов), поэтому автопоиск сработает идеально. В каком-нибудь другом примере, возможно, придётся специально придумывать уникальное слово-метку, но чаще всего будет достаточно первого пришедшего в голову описания происходящей в игре ситуации.</span></p>
<p class="rvps10"><span class="rvts22"><br/></span></p>
<p class="rvps10"><img align="right" alt="" style="padding : 6px;" src="lib/find-note.png"/></p>
<p class="rvps10"><span class="rvts22">Также может пригодиться стандартный поиск текста в Заметках. Например, полезно в ходе ТАСинга оставлять в некоторых местах Заметку со словом "TODO" – там, где нет уверенности, что найдено окончательное решение задачи (самый оптимальный Ввод на участке). И когда у вас появится настроение провести работу над ошибками, можно будет пройтись по всем Маркерам с этим тегом, вызвав окно "Find Note" (</span><span class="rvts34">Ctrl + F</span><span class="rvts22">) и введя слово "TODO" для поиска.</span></p>
<p class="rvps10"><span class="rvts22"><br/></span></p>
<p class="rvps10"><span class="rvts22">Если вам не нравится вся эта затея с Маркерами, вы вполне можете обойтись без них. В конце концов, большинство игр ставят перед ТАСером довольно простые задачи, которые не требуют высокоорганизованного подхода к процессу решения. Если задачу можно решить с наскока, конечно, не нужно тратить время на подготовку и укрепление позиций. Маркеры дают примущества в долгосрочных целях, а не в краткосрочных.</span></p>
<p class="rvps10"><span class="rvts22">Поэтому, как и в программировании, в большинстве случаев вы можете успешно писать так называемый "грязный код" (в нашем случае это проект без Маркеров и Заметок), который быстро создаётся, но плохо поддерживается и расширяется. Либо вы можете создавать любовно оформленный проект, который приятно просматривать и модифицировать. Важно понимать, что модифицировать свой мувик в попытках побить вчерашний рекорд ТАСерам приходится очень часто, поэтому затраты сегодняшнего времени на оформление проекта завтра могут окупиться тем, что сам внешний вид проекта мотивирует продолжать над ним работу.</span></p>
<p class="rvps10"><span class="rvts22"><br/></span></p>
<hr style="height: 1px; color : #000000;  background-color : #000000; border-width : 0px;"/>
<p class="rvps10"><a name="UsingLua"></a>
<span class="rvts22"><br/></span></p>
<p class="rvps10"><span class="rvts23">4. Использование Lua.</span></p>
<p class="rvps10"><span class="rvts22"><br/></span></p>
<p class="rvps10"><span class="rvts22">На языке Lua можно писать скрипты, исполняемые эмулятором FCEUX одновременно с эмуляцией игры. Для написания скриптов требуются минимальные навыки программирования, при этом спектр доступных возможностей чрезвычайно широк. Можно создавать собственные инструменты для ТАСинга, модифицировать игру во время её исполнения, получать доступ к изображению и звуку на лету, передавать данные по сети или записывать на диск и т.д. А также с помощью Lua-скриптов можно писать расширения для Тасэдитора.</span></p>
<p class="rvps10"><span class="rvts22">Для полного освоения языка Lua потребуется прочесть его документацию и набраться реального опыта, однако для создания простых скриптов будет достаточно чтения этого Руководства и </span><a class="rvts28" href="http://www.fceux.com/web/help/fceux.html?LuaScripting.html" target="_blank">раздела о Lua в Документации FCEUX</a><span class="rvts22">. Для начала попробуйте запустить чужие скрипты, созданные для FCEUX разными людьми. Они находятся в подпапке </span><span class="rvts21">/luaScripts</span><span class="rvts22">. Каждый скрипт представляет собой текстовый файл с расширением </span><span class="rvts21">.lua</span><span class="rvts22">, который можно создавать и редактировать в любом текстовом редакторе. Перед запуском скриптов нужно открыть ROM любой игры. Чтобы запустить скрипт, нужно открыть Lua-консоль (</span><span class="rvts26">File -&gt; Lua -&gt; New Lua Script Window</span><span class="rvts22">), в появившемся окне нажать кнопку "</span><span class="rvts32">Browse</span><span class="rvts22">" и загрузить файл желаемого скрипта, затем нажать кнопку "</span><span class="rvts32">Run</span><span class="rvts22">". Если эмулятор при этом стоит на паузе, требуется либо снять паузу, либо нажать </span><span class="rvts27">Frame Advance</span><span class="rvts22">, чтобы скрипт начал работать. А саму Lua-консоль можно скрыть, чтобы её окно не загораживало экран.</span></p>
<p class="rvps10"><span class="rvts22">Программный код в Lua-скриптах для FCEUX обычно делится на две части – одна часть скрипта выполняется сразу в момент запуска скрипта, другая выполняется при наступлении определённых событий эмуляции, таких как окончание эмуляции очередного кадра, загрузка сэйва и т.д.</span></p>
<p class="rvps10"><span class="rvts22">Та часть кода, которая исполняется в момент запуска скрипта, обычно выполняется однократно (если, конечно, вы не организовали в ней бесконечный цикл). Код выполняется построчно, сверху вниз. Обычно основная задача этой части – инициализировать глобальные переменные и зарегистрировать функции, которые затем будут автоматически запускаться эмулятором FCEUX при наступлении определённых событий.</span></p>
<p class="rvps10"><span class="rvts22">В большинстве случаев основной код скрипта находится внутри одной функции, которая автоматически выполняется в конце каждого кадра. Например, так может выглядеть код рисования хитбокса Марио для игры SMB:</span></p>
<p class="rvps10"><span class="rvts22"><br/></span></p>
<div class="rvps10"><table width="98%" border="1" cellpadding="6" cellspacing="2" style="border-color: #000000; border-style: solid;">
<tr valign="top">
<td style="border-color: #000000; border-style: solid;"><p class="rvps2"><span class="rvts56">marioWidth = 16</span></p>
<p class="rvps2"><span class="rvts56">marioHeight = 32</span></p>
<p class="rvps2"><span class="rvts56"><br/></span></p>
<p class="rvps2"><span class="rvts56">function everyframe()</span></p>
<p class="rvps2"><span class="rvts56"></span><span class="rvts56"> &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="rvts56">marioX = memory.readbyte(0x3AD)</span></p>
<p class="rvps2"><span class="rvts56"></span><span class="rvts56"> &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="rvts56">marioY = memory.readbyte(0xCE)</span></p>
<p class="rvps2"><span class="rvts56"></span><span class="rvts56"> &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="rvts56">gui.drawbox(marioX, marioY, marioX + marioWidth, marioY + marioHeight)</span></p>
<p class="rvps2"><span class="rvts56">end</span></p>
<p class="rvps2"><span class="rvts56"><br/></span></p>
<p class="rvps2"><span class="rvts56">emu.registerafter(everyframe)</span></p>
</td>
</tr>
</table>
</div>
<p class="rvps10"><span class="rvts22"><br/></span></p>
<p class="rvps10"><span class="rvts22">При активации этого скрипта FCEUX создаст и инициализирует две переменные ("marioWidth" и "marioHeight"), а затем зарегистрирует функцию с названием everyframe() на событие окончания каждого кадра (registerafter). После этого текст в скрипте заканчивается, и скрипт перестаёт выполняться, однако зарегистрированная функция остаётся в памяти эмулятора, и если теперь вы отпустите паузу или начнёте нажимать </span><span class="rvts27">Frame Advance</span><span class="rvts22">, после каждого кадра будет запускаться код, находящийся внутри функции everyframe(). Этот код состоит из трёх строк. Первые две создают переменные, отвечающие за координаты хитбокса, и инициализируют их текущими значениями из оперативной памяти (RAM) эмулируемой приставки. Третья строчка рисует графику поверх изображения игры.</span></p>
<p class="rvps10"><span class="rvts22">Конкретные адреса ячеек оперативной памяти можно взять из публичных источников (например, </span><a class="rvts28" href="http://tasvideos.org/GameResources/NES/SuperMarioBros.html" target="_blank">http://tasvideos.org/GameResources/NES/SuperMarioBros.html</a><span class="rvts22">) или найти самостоятельно с помощью инструментов Cheat Search или RAM Search, встроенных в FCEUX. В данном случае нам известно, что по адресу </span><span class="rvts56">0x3AD </span><span class="rvts22">в игре хранится координата X Марио, а по адресу </span><span class="rvts56">0xCE</span><span class="rvts22"> – координата Y. Поэтому от скрипта требуется только взять их текущие значения и нарисовать прямоугольник на соответствующем месте экрана. Иногда приходится пересчитывать эти значения, чтобы перевести внутриигровые координаты в экранные координаты, но в данном случае они совпадают.</span></p>
<p class="rvps10"><span class="rvts22">Про стандартные функции readbyte() и drawbox(), а также про другие полезные функции написано в </span><a class="rvts28" href="http://www.fceux.com/web/help/fceux.html?LuaFunctionsList.html" target="_blank">документации эмулятора FCEUX</a><span class="rvts22">. Там же написано про использование математических выражений, организацию циклов и условий.</span></p>
<p class="rvps10"><span class="rvts22">Про стандартные функции, доступные только при запущенном Тасэдиторе, написано в </span><a class="rvts28" href="LuaAPI.html">Справочнике</a><span class="rvts22">. Используя все эти знания, можно не только рисовать и выводить надписи поверх экрана приставки, но и контролировать Проигрыватель и Выделение, а главное, изменять Ввод и Маркеры мувика.</span></p>
<p class="rvps10"><span class="rvts22">Например, вот так может выглядеть код, копирующий Ввод первого джойстика на место второго джойстика:</span></p>
<p class="rvps10"><span class="rvts22"><br/></span></p>
<div class="rvps10"><table width="98%" border="1" cellpadding="6" cellspacing="2" style="border-color: #000000; border-style: solid;">
<tr valign="top">
<td style="border-color: #000000; border-style: solid;"><p class="rvps2"><span class="rvts56">function doCopy()</span></p>
<p class="rvps2"><span class="rvts56"></span><span class="rvts56"> &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="rvts56">selection_table = taseditor.getselection()</span></p>
<p class="rvps2"><span class="rvts56"></span><span class="rvts56"> &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="rvts56">if (selection_table ~= nil) then</span></p>
<p class="rvps2"><span class="rvts56"></span><span class="rvts56"> &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="rvts56"> &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="rvts56">for i = 1, #selection_table do</span></p>
<p class="rvps2"><span class="rvts56"></span><span class="rvts56"> &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="rvts56"> &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="rvts56"> &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="rvts56">selected_frame = selection_table[i]</span></p>
<p class="rvps2"><span class="rvts56"></span><span class="rvts56"> &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="rvts56"> &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="rvts56"> &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="rvts56">joypad1data = taseditor.getinput(selected_frame, 1)</span></p>
<p class="rvps2"><span class="rvts56"></span><span class="rvts56"> &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="rvts56"> &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="rvts56"> &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="rvts56">taseditor.submitinputchange(selected_frame, 2, joypad1data)</span></p>
<p class="rvps2"><span class="rvts56"></span><span class="rvts56"> &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="rvts56"> &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="rvts56">end</span></p>
<p class="rvps2"><span class="rvts56"></span><span class="rvts56"> &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="rvts56"> &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="rvts56">taseditor.applyinputchanges("Copy 1P-&gt;2P")</span></p>
<p class="rvps2"><span class="rvts56"></span><span class="rvts56"> &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="rvts56">end</span></p>
<p class="rvps2"><span class="rvts56">end</span></p>
<p class="rvps2"><span class="rvts56"><br/></span></p>
<p class="rvps2"><span class="rvts56">taseditor.registermanual(doCopy, "Copy 1P to 2P")</span></p>
</td>
</tr>
</table>
</div>
<p class="rvps10"><span class="rvts22"><br/></span></p>
<p class="rvps10"><span class="rvts22">При запуске этого скрипта FCEUX зарегистрирует функцию doCopy() на событие нажатия кнопки "</span><span class="rvts32">Run function</span><span class="rvts22">"</span><span class="rvts32"> </span><span class="rvts22">(registermanual). Теперь при любом нажатии этой кнопки будет запускаться код этой функции, который состоит из девяти строк. Сначала функция получает от Тасэдитора информацию о Выделении, и если оно не пустое (то есть выделен хотя бы один кадр в Piano Roll), то запускается цикл FOR, перебирающий все выделенные кадры по порядку, начиная с первого и заканчивая последним. Для каждого выделенного кадра функция запрашивает у Тасэдитора Ввод первого игрока (и сохраняет в переменную "joypad1data"), затем делает заявку на изменение Ввода второго игрока в этом же кадре. Все заявки накапливаются в памяти Тасэдитора до завершения цикла FOR, после чего они все разом исполняются с помощью вызова applyinputchanges(). В итоге Ввод второго джойстика в выделенных кадрах будет совпадать с Вводом первого джойстика.</span></p>
<p class="rvps10"><img align="right" alt="" style="padding : 6px;" src="lib/lua-run-manual.png"/></p>
<p class="rvps10"><span class="rvts22">Этот весьма простой скрипт уже представляет из себя полезный мини-инструмент, который может пригодиться вам при создании ТАСов &nbsp;с управлением двумя игроками одновременно. После запуска этого скрипта вы во время ТАСинга сможете выделять в Piano Roll ряд кадров и нажимать кнопку "</span><span class="rvts32">Copy 1P to 2P</span><span class="rvts22">" (или хоткей "</span><span class="rvts26">Run Manual Lua function</span><span class="rvts22">") для синхронизации обоих игроков. Каждый раз, когда в результате действий этого скрипта изменяется Ввод, происходит естественное усечение Гринзоны и добавление записи в Журнал Истории, чтобы при необходимости можно было откатить произведённые скриптом изменения. Таким образом вы получаете полностью интегрированную в Тасэдитор фичу, поведение которой запрограммировали сами.</span></p>
<p class="rvps10"><span class="rvts22">Хотя вы можете успешно ТАСить и без знания языка Lua, его использование может значительно сэкономить вам время и даже натолкнуть на неочевидные решения при оптимизации Ввода (а точнее, при анализе игрового Вывода).</span></p>
<p class="rvps10"><span class="rvts22">Очень часто видеоигры скрывают от игрока существенные детали происходящего, и ТАСеру приходится просматривать состояние памяти напрямую, чтобы точно ориентироваться в ситуации и ощущать факторы оптимальности во время шлифовки участков.</span></p>
<p class="rvps10"><span class="rvts22">Например, во многих играх счётчик жизней босса не показывается на экране. Поэтому, чтобы точно знать данные о нанесении урона, ТАСеру необходимо просматривать числовое значение соответствующей ячейки RAM с помощью инструмента Memory Watch. А когда таких скрытых факторов много (например, несколько таймеров неуязвимости и атак босса, а также особые счётчики самого игрового персонажа), ТАСеру приходится просматривать и анализировать множество ячеек памяти, значения которых колеблются по разнообразным законам. В этом случае большим подспорьем будет визуализация некоторых данных на экране эмулятора. Например, счётчик жизней босса можно изобразить в виде полоски или числа над его головой, причём красным цветом можно акцентировать кадры нанесения урона или ещё какие-нибудь события. В результате вы неплохо разгружаете голову, переходя от формата абстрактных данных, которые требуется расшифровывать, к формату, который сразу доводит основную мысль (например, "удар по боссу сработал", "хорошо/плохо").</span></p>
<p class="rvps10"><span class="rvts22">Поэтому рекомендуется освоить Lua хотя бы на уровне осмысленной модификации чужих скриптов. За долгое время существования FCEUX было написано и опубликовано множество скриптов, выполняющих самые разные цели, и возможно, вам потребуется только изменить в чужом скрипте адреса ячеек RAM, подстроив его под свою игру. Порой также имеет смысл попросить помощи на </span><a class="rvts28" href="http://tasvideos.org/forum/viewforum.php?f=25" target="_blank">форуме TASVideos</a><span class="rvts22">.</span></p>
<p class="rvps10"><span class="rvts22"><br/></span></p>
<hr style="height: 1px; color : #000000;  background-color : #000000; border-width : 0px;"/>
<p class="rvps10"><span class="rvts22"><br/></span></p>
<p class="rvps10"><span class="rvts22">Курс по изучению Тасэдитора подошёл к концу. Если вы внимательно подошли к чтению, теперь вы знаете всё, что требуется для создания ТАСов на уровне TASVideos. Осталось лишь набраться опыта в реальной работе, довести большинство действий до автоматизма, чтобы не чувствовать рутину, а просто получать удовольствие от процесса вооружённого прохождения и исследования видеоигр.</span></p>
<p class="rvps10"><span class="rvts22"><br/></span></p>
<p class="rvps10"><span class="rvts22"><br/></span></p>
<p class="rvps10"><span class="rvts22"><br/></span></p>
<p class="rvps10"><span class="rvts22"><br/></span></p>
<p class="rvps10"><span class="rvts22"><br/></span></p>
<p></p>
<p class="rvps8"><span class="rvts18">Created with the Personal Edition of HelpNDoc: </span><a class="rvts19" href="http://www.helpndoc.com/help-authoring-tool">Single source CHM, PDF, DOC and HTML Help creation</a></p>
</div>
	
	<div id="topic_footer">

			<div id="topic_footer_content">
				&copy; 2011-2013 АнС</div>
		</div>
	</body>
	
</html>

